<template>
  <div class="mapBox">
    <div class="mapTitle">
      <img src="@/assets/images/lamp.png" /> <div>请拖动地图至农场所在地，然后点击“开始绘制”按钮进行地块区域绘制。</div>
    </div>
    <div id="mapWindow" v-if="mapShow"></div>
    <!-- 圈地按钮 -->
    <div class="btn">
      <!-- <el-button @click="openPolygonTool" :disabled="drawBtn"
        >开始绘制</el-button
      >-->
      <el-button class="mapWhiteBtn" v-show="lngLats.length && mapNoneClick" @click="deleteAllMarker()">重新绘制</el-button>
      <el-button class="mapGreenBtn" v-show="lngLats.length && mapNoneClick" @click="getAreaData()">完成绘制</el-button>
      <el-button class="mapGreenBtn" v-show="lngLats.length && !mapNoneClick" type="primary" @click="deleteMarker()">
        <div class="btnFlex"><img src="@/assets/images/areaBack.png" /><div>撤回</div></div>
      </el-button>
    </div>
    <div></div>
    <div class="leftShowArea">
        <div class="areaSwitchRight">
          显示已绘制的地块
        </div>
        <el-switch
          @change="showAreaSwitch()"
          v-model="activeValue"
          active-color="#13ce66"
          inactive-color="#ff4949">
      </el-switch>
    </div>
    <!-- 搜索框 -->
    <div class="left-top" v-show="mapNoneClick && !lngLats.length">
      <el-input
        v-model="input"
        placeholder="请输入关键词搜索"
        class="address-search"
        suffix-icon="el-icon-search"
        @input="searchWithName"
      >
        <!-- <el-button size="mini" @click="addressList = [],input = null" slot="append"
          >确认选中</el-button
        > -->
      </el-input>
      <div class="address-list" v-show="addressList && addressList.length">
        <div
          v-for="(item, index) in addressList"
          :key="index"
          @click="selectOneAddr(item.address + item.name)"
        >
          <div>{{ item.address }}</div>
          <div>{{ item.name }}</div>
        </div>
      </div>
    </div>
    <div class="leftButton" v-show="mapNoneClick && !lngLats.length">
      <el-button @click="mapNoneClick = false">开始绘制</el-button>
    </div>
    <div id="boxName" v-show="showBoxName && !mapNoneClick">
       {{lngLats.length === 0
        ? '绘制第一个点'
          : lngLats.length <= 2
          ? '继续绘制'
          : lngLats.length >= 3
          ? '点击第一个点可结束绘制'
          : ''}}
    </div>
  </div>
</template>

<script>
import * as turf from '@turf/turf'
export default {
  data () {
    return {
      baseGeo: null,
      activeValue: true,
      map: {},
      T: '',
      handler: null, // 圈地用的
      polygonTool: null, // 控件
      polygon: null, // 面
      currentPolygon: '',
      landData: [],
      polygonDraw: null,
      marker: null, // 地图点位
      line: null, // 地图连线
      lngLats: [], // 点位坐标
      markerList: [], //  点位数组
      addressList: [], // 搜索框
      input: '',
      drawBtn: false,
      drawData: {
        // landInfo: null
      },
      geoCenter: null,
      geocode: null,
      geoColor: '#19b560,#ccc',
      polygonPath: [],
      mapShow: true,
      address: null,
      mapNoneClick: true,
      c: false,
      geoInfoChange: '',
      polygonDrawOld: true,
      showBoxName: false,
      setTips: '<div style="width:10vw;height:2vw;background: rgba(25, 181, 96);padding:0.2vw;margin:-0.4vw 5vw 1vw -5vw;border-radius: 8px;position: absolute;top: 50%;left:-50%;">点击继续绘制，双击结束绘制</div></div>'// 绘制时显示的标签
    }
  },
  props: {
    geoInfo: {
      type: String,
      default () {
        return ''
      }
    },
    landList: {
      type: Array
    },
    isDel: {
      type: Boolean,
      default () {
        return false
      }
    }
  },
  watch: {
    // 搜索框
    input (val) {
      if (!val) {
        this.addressList = []
        // 用来清空删除太快时候出现列表的bug
        setTimeout(() => {
          this.addressList = []
        }, 3000)
      }
    }
  },
  mounted () {
    this.mapDel = this.isDel
    this.geoInfoChange = this.geoInfo
    this.baseGeo = this.$store.getters.baseData ? this.$store.getters.baseData.baseGeo : ''
    console.log(this.baseData)
    setTimeout(() => {
      this.load()
    }, 10)
  },
  methods: {
    // 显示面积
    async showAreaSwitch () {
      this.mapNoneClick = false
      if (this.marker) {
        this.marker.removeEventListener('click', this.markClick)
      }
      if (this.map) {
        this.map.removeEventListener('click', this.mapClick)
      }
      this.geoInfoChange = JSON.stringify(this.lngLats)
      this.polygonDrawOld = !!this.polygonDraw
      this.map.clearOverLays()
      this.map = null
      this.polygonDraw = null
      this.markerList = []
      this.marker = null
      this.lngLats = []
      await this.load()
    },
    // 面积 中心点计算
    async getAreaData () {
      if (!this.polygonDraw) {
        this.$message.error('请绘制地块')
        return
      }
      const polygonList = []
      const polygonSubmit = JSON.stringify(this.polygonDraw.getLngLats()[0])
      this.polygonDraw.getLngLats()[0].map(async (item, index) => {
        polygonList.push([item.lng, item.lat])
        if (this.polygonDraw.getLngLats()[0].length - 1 === index) {
          polygonList.unshift([item.lng, item.lat])
        }
      })
      const polygon = turf.polygon([polygonList])
      const area = turf.area(polygon)
      const polygonCenter = turf.centroid(polygon)
      const geocoder = new this.T.Geocoder()
      await geocoder.getLocation(new this.T.LngLat(polygonCenter.geometry.coordinates[0], polygonCenter.geometry.coordinates[1]), async (result) => {
        this.$emit('dataList', {
          area: parseFloat((area * 0.0015).toFixed(2)),
          polygonCenter: JSON.stringify({
            lng: polygonCenter.geometry.coordinates[0],
            lat: polygonCenter.geometry.coordinates[1]
          }),
          zoom: this.map.getZoom(),
          address: result.getAddress(),
          polygonSubmit: polygonSubmit
        })
      })
      // return turf.area(polygon, { units: 'kilometers' }).toFixed(2)
    },
    // 绘制当前地块
    drawAreaNow () {
      let indexChange = null
      this.mapNoneClick = false
      this.geoInfoChange && JSON.parse(this.geoInfoChange).map((item, index) => {
        if (index === 0) {
          indexChange = item
        }
        this.addMarker(item.lng, item.lat)
        if (JSON.parse(this.geoInfoChange).length - 1 === index && this.polygonDrawOld) {
          this.markClick({
            lnglat: {
              lng: indexChange.lng,
              lat: indexChange.lat
            }
          })
        }
      })
      this.geoInfoChange = ''
    },
    // 鼠标滑过
    getMouse () {
      const vm = this
      const box = document.getElementById('boxName')
      const mapWindow = document.getElementById('mapWindow')
      mapWindow.onmousemove = null
      mapWindow.onmouseout = null
      mapWindow.onmousemove = function (event) {
        vm.showBoxName = true
        if (event.offsetX <= 0 || event.offsetY <= 0) {
          vm.showBoxName = false
          return
        }
        const left = event.pageX
        const top = event.pageY
        // pageX和page这两个属性在IE8中不支持，所以如果需要兼容IE8，就不能使用
        // 设置div的偏移量
        box.style.left = left - (document.getElementById('boxName').offsetWidth / 2) + 'px'
        box.style.top = top + (document.getElementById('boxName').offsetHeight / 2) - 10 + 'px'
      }
      mapWindow.onmouseleave = function () {
        vm.showBoxName = false
      }
    },
    load () {
      // 地图初始化成功
      const init = new Promise((resolve, reject) => {
        if (window.T) {
          resolve(window.T)
        }
      })
      init.then((T) => {
        this.T = T
        const lay = new T.TileLayer('http://t0.tianditu.gov.cn/img_w/wmts?' +
        'SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles' +
        '&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=3608866120174dc307d1ce121ccfde22')
        this.map = new T.Map('mapWindow', { layers: [lay] })
        this.getMouse()
        // this.map.centerAndZoom(new T.LngLat(119.34084930680076, 28.490377599913185), 5)
        this.map.panTo(this.baseGeo ? new T.LngLat(this.baseGeo.split(',')[0], this.baseGeo.split(',')[1]) : new T.LngLat(119.34084930680076, 28.490377599913185), 16)
        // 如果显示绘制
        // 合并所有经纬度调用setViewport在地图上显示所有圈地
        if (this.geoCenter === null && this.landList !== []) {
          let MapArray = []
          for (let i = 0; i < this.landList.length; i++) {
            const geoArray = JSON.parse(this.landList[i].geoInfo)
            MapArray = [...MapArray, ...geoArray]
          }
          this.map.setViewport(MapArray)
        } else if (this.landData !== []) {
          this.map.setViewport(this.landData)
        }
        this.map.addEventListener('click', this.mapClick)
        // 有点击信息就显示
        if (this.geoInfoChange) {
          this.drawAreaNow()
        }
        // 判断显示地块
        if (!this.activeValue) {
          return
        }
        // 双重for循环遍历所有的地块数据进行渲染
        for (let j = 0; j < this.landList.length; j++) {
          // 编辑时判断是否是删除进去
          if (this.mapDel && this.landList[j].landId == this.$route.query.landId) {
            continue
          }
          // 编辑时当进去是显示当前地块数据
          if (this.landList[j].landId == this.$route.query.landId) {
            // this.drawAreaNow()
            continue
          }
          const geoObj = {}
          geoObj.geoInfo = JSON.parse(this.landList[j].geoInfo) // 经纬度
          geoObj.landName = this.landList[j].landName // 地块名称
          geoObj.landArea = this.landList[j].landArea // 地块名称

          const points = []
          for (let i = 0; i < geoObj.geoInfo.length; i++) {
            points.push(
              new T.LngLat(geoObj.geoInfo[i].lng, geoObj.geoInfo[i].lat)
            )
          }
          // 创建面对象
          this.polygon = new T.Polygon(points, {
            color: geoObj.landType === '田地' ? '#19B560' : '#FFD234',
            weight: 3,
            opacity: 0.5,
            fillColor: geoObj.landType === '田地' ? '#19B560' : '#FFD234',
            fillOpacity: 0.15,
            test: `<p>名称：${geoObj.landName}</p><p>面积：${geoObj.landArea}亩</p>`
          })
          // 添加点击事件
          // this.polygon.addEventListener('click', this.getinfo)
          // 向地图上添加面
          this.map.addOverLay(this.polygon)
        }

        // 添加刚绘制的面
        const points = []
        for (let i = 0; i < this.landData.length; i++) {
          points.push(new T.LngLat(this.landData[i].lng, this.landData[i].lat))
        }
        // 创建面对象
        const color = this.geoColor.split(',').map(color => color.trim())
        this.polygon = new T.Polygon(points, {
          color: color[0], // 线
          weight: 3,
          opacity: 0.5,
          fillColor: color[1], // 面
          fillOpacity: 0.5
          // test: '<p>名称：梅林村稻田1区</p><p>面积：295亩</p>'
        })
        // 向地图上添加面
        this.map.addOverLay(this.polygon)
        // 地图图层
        // const ctrl = new T.Control.MapType([

        //   {
        //     title: '卫星',
        //     icon: 'http://api.tianditu.gov.cn/v4.0/image/map/maptype/satellite.png',
        //     layer: window.TMAP_HYBRID_MAP
        //   }
        //   // {
        //   //   title: '地图',
        //   //   icon: 'http://api.tianditu.gov.cn/v4.0/image/map/maptype/vector.png', // 地图控件上所要显示的图层图标（默认图标大小80x80）
        //   //   layer: window.TMAP_NORMAL_MAP
        //   // }
        // ])
        // this.map.addControl(ctrl)
      })
    },
    // 点击地图
    mapClick (e) {
      this.addMarker(e.lnglat.getLng(), e.lnglat.getLat())
    },
    polyLine () {
      // 清除画线
      if (this.line) {
        this.map.removeOverLay(this.line)
      }
      const points = []
      this.lngLats.forEach(item => {
        points.push(new this.T.LngLat(item.lng, item.lat))
      })
      this.line = new this.T.Polyline(points, {
        showLabel: false, // 测距功能展示
        color: '#FFFFFF',
        weight: 2,
        opacity: 1,
        fillColor: '#FFFFFF',
        fillOpacity: 1
      })
      this.map.addOverLay(this.line)
    },
    // 重新绘制
    deleteAllMarker () {
      if (this.polygonDraw) {
        this.polygonDraw.disableEdit()
        this.polygonDraw.onRemove()
        this.polygonDraw = null
      }
      this.markerList.map(item => {
        this.map.removeOverLay(item)
      })
      this.markerList = []
      this.lngLats = []
      this.polyLine()
      this.mapNoneClick = true
    },
    // 地图删除坐标图标
    deleteMarker () {
      this.mapNoneClick = false
      if (this.polygonDraw) {
        this.polygonDraw.disableEdit()
        this.polygonDraw.onRemove()
        this.polygonDraw = null
      } else {
        this.lngLats.splice(-1, 1)
        this.map.removeOverLay(this.markerList[this.markerList.length - 1])
        this.markerList.splice(-1, 1)
      }
      if (!this.markerList.length) {
        this.mapNoneClick = true
        return
      }
      this.polyLine()
    },
    // 地图点击事件
    addMarker (getLng, getLat) {
      if (this.mapNoneClick) {
        return true
      }
      // if (this.marker) {
      //   this.map.removeOverLay(this.marker)
      // }
      const icon = new this.T.Icon({
        iconUrl: require('@/assets/images/drop.png'),
        iconSize: new window.T.Point(15, 15)
        // iconAnchor: new window.T.Point(10, 56)
      })
      const point = new this.T.LngLat(getLng, getLat)
      this.marker = new this.T.Marker(point, {
        icon
      }) // 创建标注
      this.lngLats.push({
        lng: getLng,
        lat: getLat
      })
      this.markerList.push(this.marker) // 方便删除
      this.marker.addEventListener('click', this.markClick)
      this.map.addOverLay(this.marker) // 将标注添加到地图中
      this.polyLine()
    },
    // 标注点击事件
    markClick (e) {
      if (this.lngLats.length <= 2 || this.mapNoneClick) {
        return
      }
      if (e.lnglat.lng === this.lngLats[0].lng && e.lnglat.lat === this.lngLats[0].lat) {
        this.$set(this, 'mapNoneClick', true)
        this.polygonDraw = new this.T.Polygon([...this.lngLats], {
          color: '#ffffff',
          weight: 2,
          opacity: 1,
          fillColor: 'rgba(0, 197, 134, 1)',
          fillOpacity: 0.5
        })
        this.polygonDraw.enableEdit()
        // 向地图上添加面
        this.map.addOverLay(this.polygonDraw)
        this.map.removeOverLay(this.line)
        this.markerList.map(item => {
          this.map.removeOverLay(item)
        })
      }
    },
    getinfo (e) {
      const T = this.T
      const that = this
      const p = e.target
      const lnglat = new T.LngLat(p.getCenter().lng, p.getCenter().lat) // 获取点击多边形中心经纬度
      const infoWin = new T.InfoWindow() // 创建信息窗口对象
      const Content = e.target.options.test // 设置信息窗口要显示的内容，此处可使用html代码;现在显示的就是之前在polygon实例中添加的数据
      infoWin.setContent(Content) // 信息窗口加入信息
      infoWin.setOffset(new T.Point(0, -30)) // 设置信息窗口边距，第一个决定X方向，第二个决定Y方向
      infoWin.setLngLat(lnglat) // 设置信息窗口位置
      that.map.addOverLay(infoWin) // 向地图上添加信息窗口
    },
    // 搜索 天地图LocalSearch
    searchWithName (val) {
      if (val) {
        const that = this
        const config = {
          pageCapacity: 10, // 每页显示的数量
          onSearchComplete: localSearchResult // 接收数据的回调函数
        }
        // 创建搜索对象
        const T = this.T
        const localsearch = new T.LocalSearch(that.map, config)
        localsearch.search(that.input, 1)
        function localSearchResult (result) {
          // 清空地图及搜索列表
          // clearAll()
          // 解析建议词信息
          // result.getPois()
          suggests(result.getPois())
        }
        // 解析建议词信息
        function suggests (obj) {
          if (obj && obj.length) {
            that.addressList = obj
          }
        }
        // 清空地图及搜索列表
        // function clearAll () {
        //   that.map.clearOverLays()
        // }
      } else {
        this.addressList = []
      }
    },
    // 点击搜索内容地图跳转
    selectOneAddr (val) {
      const that = this
      const T = this.T
      that.map.clearOverLays()
      // 创建对象
      const geocoder = new T.Geocoder()
      geocoder.getPoint(val, searchResult)
      this.input = ''
      function searchResult (result) {
        if (result.getStatus() === 0) {
          that.map.panTo(result.getLocationPoint(), 16)
          that.address = val
          that.$emit('setAddress', val)
          that.lng = result.getLocationPoint().lng
          that.lat = result.getLocationPoint().lat
          that.$emit('setPosition', [
            result.getLocationPoint().lng,
            result.getLocationPoint().lat
          ])
        } else {
          this.$message.warning('定位出错请重新选择')
        }
      }
    }
  }
}
</script>
<style lang="scss" scoped>
.mapTitle {
  display: flex;
  align-items: center;
  color: #000000;
  margin-bottom: 15px;
  padding-top: 15px;
  img {
    width: 20px;
    margin-right: 5px;
  }
}
#mapWindow {
  width: 100%;
  height: 60vh;
}

.mapBox {
  position: relative;
}
.btn {
  position: absolute;
  bottom: 4.5%;
  right: 0;
  left: 0;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 999;
}
#right-btn {
  visibility: hidden;
  position: absolute;
  top: 0px;
  left: 0px;
  z-index: 999;
  background-color: #fff;
  cursor: pointer;
  border: 1px solid #dee1e6;
}

.right-item {
  margin: 4px;
  font-size: 12px;
}

.right-item:hover {
  color: #23aaf2;
}
::v-deep .tat-label1 {
  border: none !important;
  background-color: transparent !important;
}
</style>

<style lang="stylus" scoped>
.cur {
  cursor: pointer;
}

.map-address {
  height: 60vh;
}

#mapDiv {
  height: 100%;
  position: relative;
}
.leftShowArea {
  position: absolute;
  left: 1%;
  height: 36px;
  display: flex;
  align-items: center;
  top: 65px;
  background: #fff;
  z-index: 999;
  border-radius: 3px;
  padding: 0 20px;
  .areaSwitchRight {
    margin-right: 8px
  }
}
.left-top {
  position: absolute;
  right: calc(2% + 115px);
  top: 65px;
  z-index: 1000
}
.leftButton {
  position: absolute;
  right: 2%;
  top: 65px;
  background: #fff;
  z-index: 999;
  border-radius: 3px;
}
.address-search {
  width: 18vw;
  z-index: 10000;
  margin-bottom: 20px;
}

.address-list {
  display: flex;
  flex-direction: column;
  z-index: 10000;
  background-color: #fff;
  padding: 10px;
  min-width: 18vw;
  border: 1px solid #DCDFE6;

  >div {
    display: flex;
    align-items: center;
    height: 30px;
    cursor: pointer;
    color: #409eff;

    &:hover {
      background-color: #eee;
    }
  }
}
::v-deep .tdt-div-icon-black {
  border: none !important;
  background: url('~@/assets/images/drop.png');
  background-size: 100% 100%;
  width: 15px !important;
  height: 15px !important;
  margin-left: -7.5px !important;
  margin-top: -7.5px !important;
}
#boxName {
  background: url('~@/assets/images/boxName.png');
  background-size: 100% 100%;
  padding: 15px 10px 10px 10px;
  min-width: 80px;
  color: #fff;
  display: inline-block;
  text-align: center;
  position: fixed;
  z-index: 99999
}
</style>
